package czopyk.model.factories;

import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.atomic.AtomicLong;

import model.Time;

import org.apache.commons.lang.StringUtils;

import cern.jet.random.engine.MersenneTwister;
import cern.jet.random.engine.RandomEngine;

import com.espertech.esper.collection.Pair;

import czopyk.model.request.CompositeRequest;
import czopyk.model.request.Request;

public class Utils {

	private static Integer seed = null;

	public static final RandomEngine getNewRandomEngine() {
		return new MersenneTwister(seed == null ? (int) System.currentTimeMillis()
				: seed);
		// new DRand((int) System.currentTimeMillis());
	}

	private static final AtomicLong al = new AtomicLong(0);

	public static long nextId() {
		synchronized (Utils.class) {
			return al.getAndIncrement();
		}
	}
	
	public static void recursiveDone(Request r) {
		if (r.isDone() || !(r instanceof CompositeRequest)) {
			return;
		}
		boolean done = true;
		for (Request e : ((CompositeRequest) r).getComponents()) {
			recursiveDone(e);
			if (!e.isDone()) {
				done = false;
			}
		}
		if (done) {
			r.done("recursive update");
		}
	}
	
	/**
	 * @param id
	 * @param prefix
	 * @param clock
	 * @return Observer wypisujący clock:prefix i wartosc pair.second
	 */
	public static Observer getPairUpdateListener(final long id,
			final String prefix) {
		return new Observer() {
			@SuppressWarnings({ "unchecked", "rawtypes" })
			public void update(Observable o, Object arg) {
				if (arg instanceof Pair && ((Pair) arg).getFirst().equals(id)) {
					System.out.println(StringUtils.rightPad((Time.currentTime() + ":"), 20)
							+ prefix + ((Pair<Long, Double>) arg).getSecond());
				}
			}
		};

	}

	public static Integer getSeed() {
		return seed;
	}

	public static void setSeed(Integer seed) {
		Utils.seed = seed;
	}

	public static long round(double d) {
		long r = Math.round(d);
		r = r > 0 ? r : 1;
		//System.out.println(d + " -> " + r);
		return r;
	}
	
}
